package com.polaris.live.ui.live.fragment

import android.os.Bundle
import android.view.View
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.ScreenUtils
import com.gyf.immersionbar.ImmersionBar
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.enums.PopupPosition
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.ext.formatNumberWithK
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.network.parseState
import com.polaris.live.common.util.LazyUtils
import com.polaris.live.common.util.LogExt
import com.polaris.live.common.util.NavigationBarUtils
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.constant.LiveConst
import com.polaris.live.constant.UserConst
import com.polaris.live.databinding.FragmentLiveSpectatorBinding
import com.polaris.live.dialog.GlobalDialogManager
import com.polaris.live.dialog_fragment.RoomInvitationFragmentDialog
import com.polaris.live.dialog_fragment.magiclamp.MagicLampPopup
import com.polaris.live.im.manager.ImLiveManager
import com.polaris.live.im.manager.OnLiveObserveListener
import com.polaris.live.im.manager.RouterControlManager
import com.polaris.live.im.sfs.COMMAND_LIVE_CLOSE
import com.polaris.live.im.sfs.COMMAND_LIVE_FLOATING
import com.polaris.live.im.sfs.LIVE_GIFT_LIST
import com.polaris.live.im.sfs.LIVE_KICK_ROOM
import com.polaris.live.im.sfs.LIVE_MAGIC_LAMP_90
import com.polaris.live.im.sfs.LIVE_MAGIC_LAMP_OPEN
import com.polaris.live.im.sfs.LIVE_MASKING_MESSAGE
import com.polaris.live.im.sfs.LIVE_PUBLIC_SCREEN
import com.polaris.live.im.sfs.LIVE_SEND_GIFT
import com.polaris.live.im.sfs.LIVE_WARN_MESSAGE
import com.polaris.live.im.sfs.LUCKY_BACKPACK_GIFT
import com.polaris.live.im.sfs.NEW_COUPLES_FREE_GIFTS
import com.polaris.live.im.sfs.bean.live.LivePublicScreenMessage
import com.polaris.live.im.sfs.bean.live.LiveRoomInfo
import com.polaris.live.im.sfs.bean.live.SendLiveCloseMessage
import com.polaris.live.im.sfs.bean.live.SendLiveFloatingMessage
import com.polaris.live.im.sfs.bean.live.ext.LiveEnterBean
import com.polaris.live.im.sfs.bean.live.ext.MessageUserExtBean
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo
import com.polaris.live.im.sfs.bean.live.payload.GiftListPayloadBean
import com.polaris.live.im.sfs.bean.live.payload.InviteGiftPayloadBean
import com.polaris.live.im.sfs.bean.live.toUserBasic
import com.polaris.live.im.sfs.core.SmartFoxManager
import com.polaris.live.im.sfs.core.bean.getRoomId
import com.polaris.live.im.utils.SmartFoxUtils.parseVariables
import com.polaris.live.interface_bag.XpopupCallBackImpl
import com.polaris.live.manager.AppConfigManager
import com.polaris.live.manager.UserStateManager
import com.polaris.live.popup.ContributionListPopup
import com.polaris.live.popup.GameListPopup
import com.polaris.live.popup.GamePlayWinPopup
import com.polaris.live.popup.GlobalPopupManager
import com.polaris.live.popup.LiveDrawerPopup
import com.polaris.live.popup.MagicLampWinRewardPopup
import com.polaris.live.popup.VipBarrageWhatPopup
import com.polaris.live.resp.back_resp.DisplayUserBean
import com.polaris.live.resp.back_resp.GiftBean
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.resp.back_resp.toDisplayUserBean
import com.polaris.live.resp.back_resp.toUserBasicVo
import com.polaris.live.resp.bean.MagicLampCountDownBean
import com.polaris.live.resp.go_resp.SendGiftBean
import com.polaris.live.translation.R
import com.polaris.live.ui.game.GameUtils
import com.polaris.live.ui.live.bean.LiveDisplayUserVo
import com.polaris.live.ui.live.bean.LiveInitInfo
import com.polaris.live.ui.live.bean.LiveSpectatorBean
import com.polaris.live.ui.live.bean.toLiveSpectatorBean
import com.polaris.live.ui.live.fragment.base.DragFragment
import com.polaris.live.ui.live.proxy.LiveMoreProxy
import com.polaris.live.ui.live.proxy.LivePublicProxy
import com.polaris.live.ui.live.proxy.gift.EntryScreenAnimationProxy
import com.polaris.live.ui.live.proxy.gift.GiftAnimationProxy
import com.polaris.live.ui.live.widget.LiveFloatView
import com.polaris.live.ui.live.widget.listener.OnLiveNetworkListener
import com.polaris.live.ui.live.widget.listener.OnPlayerQualityState
import com.polaris.live.ui.live.widget.listener.OnSendPublicMessageListener
import com.polaris.live.ui.live.widget.listener.OnSwitchRoomListener
import com.polaris.live.ui.message.fragment.MessageSessionFragment
import com.polaris.live.ui.message.fragment.dialog.MessageSessionDialogFragment
import com.polaris.live.ui.message.fragment.dialog.MessageSingleDialogFragment
import com.polaris.live.utils.LiveUtils
import com.polaris.live.utils.StartCallProxy
import com.polaris.live.utils.TaskRedListener
import com.polaris.live.utils.TaskRedProxy
import com.polaris.live.utils.fragment.showNewDialogFragment
import com.polaris.live.utils.route.RoutePath
import com.polaris.live.utils.route.Router
import com.polaris.live.utils.route.RouterUtils
import com.polaris.live.viewmodel.live.LiveVideoViewModel
import im.zego.zegoexpress.entity.ZegoPlayStreamQuality
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import sfs2x.client.core.SFSEvent
import sfs2x.client.entities.variables.RoomVariable

/**
 * SpectatorFragment
 *
 * @author Created by lucas on 2023/11/7 13:53
 */
class LiveSpectatorFragment : DragFragment<LiveVideoViewModel, FragmentLiveSpectatorBinding, LiveSpectatorBean>(),
    OnLiveNetworkListener, OnPlayerQualityState, OnSwitchRoomListener {

    private var mAnchorId: Long = -1
    private var mLiveInfo: LiveRoomInfo? = null

    private var mAnchorLeave: Boolean = true  //主播是否离开
    private var mLastUserCount: Int = 0  //最后人数

    private var mLiveMoreAttempt: Int = 1
    private var mLiveMoreData: LiveDisplayUserVo? = null

    //礼物代理
    private var mGiftProxy: GiftAnimationProxy? = null

    //h5转跳后如果 主播id与路由的主播id不同先切换房间 然后存储的子路由
    private var mH5ChildRouter: String? = null

    /**
     * 进场动效代理
     */
    private var mEntryScreenAnimationProxy: EntryScreenAnimationProxy? = null
    private val mLivePublicProxy by lazy {
        LivePublicProxy(requireContext(), mViewModel)
    }

    //礼物列表消息  延迟后添加快捷礼物列表
    private var mGiftJob: Job? = null

    private var mIsShowDrawer = false // 判断抽屉的直播列表是否展示
    private val mLiveDrawerPopup: LiveDrawerPopup by lazy {
        LiveDrawerPopup(requireActivity()) { switchLive(it) }
    }

    private var mOnScrollViewListener: OnScrollViewListener? = null
    private var mOnSwitchLiveListener: OnSwitchLiveListener? = null

    private var mOnCloseListener: ((SendLiveCloseMessage?) -> Unit)? = null
    private var mOnServerCloseListener: ((SendLiveCloseMessage?) -> Unit)? = null

    private val mLiveMoreProxy by lazy {
        LiveMoreProxy(
            requireContext(), this, mViewModel,
            LiveSpectatorFragment.pageType,
            null,
            null
        )
    }

    private fun initImmersionBar() {
        ImmersionBar.with(this)
            .transparentBar()
            .titleBarMarginTop(mBinding.rlContent)
            .init()

        NavigationBarUtils.setNavigationHeight(mBinding.rlContent)
        NavigationBarUtils.setNavigationHeight(mBinding.consBottom)
    }

    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)

        initImmersionBar()

        mAnchorId = arguments?.getLong("anchorId", -1L) ?: -1

        mBinding.apply {
            vFooter.attachEditView(vEdit)
            vFooter.attachComboView(icRun)

            vFooter.initUI(pageType, mViewModel)
        }

        mEntryScreenAnimationProxy =
            EntryScreenAnimationProxy(
                requireActivity(),
                mBinding.entryFloatingScreen,
                mBinding.entryScreen,
                viewLifecycleOwner
            )

        initListener()
        initObserver()
        mViewModel.getBackGiftRed()
        mBinding.actMarquee.getActivitiesScroll(mViewModel, mAnchorId)
    }

    //点击监听
    private fun initListener() {
        /**
         * 观众点击了，吊起礼物盘
         */
        mBinding.actMarquee.setGiftIdBackListener {
            mBinding.vFooter.showGiftDialog(null, it)
        }

        //直播间飘屏被点击
        mBinding.widgetFloat.setOnSingleClickListener { data ->
            when (data.type) {
                LiveFloatView.GIFT -> { //礼物飘屏
                    RouterUtils.getAnchorId(data.router)?.let { id ->
                        if (mAnchorId != id) {
                            mViewModel.getGiftInfoUser(id)
                        }
                    }
                }

                LiveFloatView.GAME -> { //游戏中奖
                    GameUtils.showAndCheckGameFragment(
                        requireContext(),
                        mLiveInfo?.userId,
                        data.payload
                    )
                }

                LiveFloatView.ROOM -> { //开房通知
                    data.router?.let {
                        val pathUrl = RouterUtils.routerGetPath(it)
                        RouterUtils.killTopActivity(it, pathUrl)
                    }
                }

                LiveFloatView.GENERAL -> { //通用
                    data.router?.let {
                        RouterUtils.routerGoto(it)
                    }
                }
            }
        }
        mBinding.apply {
            //退出直播
            icBack.setOnSingleClickListener {
                mOnCloseListener?.invoke(null)
            }
            //直播间用户列表
            vHeader.setOnConsumeItemClickListener { _, item ->
                showUserProfilePopup(item.userId)
            }
            //点击主播头像
            vHeader.setOnAvatarClientListener {
                mLiveInfo?.userId?.also { anchorId ->
                    showUserProfilePopup(anchorId)
                }
            }
            //点击关注
            vHeader.setOnFollowerClickListener {
                mLiveInfo?.userId?.also { userId ->
                    mLiveInfo?.liveId?.let { it1 -> mViewModel.addLiveFollow(userId, it1) }
                }
            }
            //点击在线列表
            vHeader.setOnOnlineClickListener {
                mLiveInfo?.let {
                    GlobalPopupManager.showOnlineUser(
                        requireContext(),
                        this@LiveSpectatorFragment,
                        mViewModel,
                        it.liveId,
                        it.userId,
                        LiveConst.Type.LIVE_AND_MATCH,
                        onHeadClickListener = {
                            showUserProfilePopup(it)
                        },
                        onSendGiftSomeOneCallback = {
                            it ?: return@showOnlineUser
                            Router.builder(RoutePath.USER_SPACE_ACTIVITY)
                                .withInt("page", UserConst.From.HOT)
                                .withLong("userId", it.userId)
                                .withAny("userBasic", it)
                                .navigation(requireActivity())
                        }
                    )
                }
            }
            //赠送礼物
            vMessage.getMessageView().setOnSendGiftListener {
                mViewModel.sendGift(requireContext(), it, LiveConst.SendGift.publicGift)
            }
            //赠送关注礼物
            vMessage.getMessageView().setOnSendFollowerListener {
                mViewModel.sendGift(requireContext(), it, LiveConst.SendGift.followerGift)
                vHeader.updateFollowStatus(true)
            }
            //打电话
            vMessage.setOnCallClickListener { otherId, formType, lastFromType, senderFrom ->
                StartCallProxy.builder(this@LiveSpectatorFragment).startCall(
                    mViewModel,
                    formType,
                    lastFromType,
                    senderFrom,
                    otherId,
                    mLiveInfo?.toUserBasic()
                )
            }
            //公屏举报
            vMessage.getMessageView().setOnReportListener {
                if (it.ext is MessageUserExtBean) {
                    GlobalPopupManager.showReport(
                        requireContext(), it.ext.user.nickname,
                        mViewModel, it.ext.user.userId, mLiveInfo?.liveId
                    )
                }
            }
            //显示头像
            vMessage.getMessageView().setOnUserProfileClickListener {
                showUserProfilePopup(it)
            }
            vEdit.setOnSendPublicMessageListener(object : OnSendPublicMessageListener {
                override fun onSendPublicMessage(message: LivePublicScreenMessage) {
                    mViewModel.sendPublicMessage(message)
                }

                override fun onBarrageWhat() {
                    VipBarrageWhatPopup.showPop(requireContext(), true) {
                        Router.instance.setPath(RoutePath.VIP_CENTER_ACTIVITY)
                            .withInt("page", 0)
                            .withInt("level", 6)
                            .navigation(requireContext())
                    }
                }
            })
            //发送礼物
            vFooter.setOnSendGiftListener {
                mViewModel.sendGift(requireContext(), it, LiveConst.SendGift.giftPopup)
            }
            vFooter.setOnMessageClickListener {
                childFragmentManager.showNewDialogFragment(
                    MessageSessionDialogFragment(if (mAnchorId == -1L) null else mAnchorId),
                    MessageSessionDialogFragment.FRAGMENT_TAG
                )
            }
            //点击与主播打电话
            vFooter.setOnCallClickListener {
                mLiveInfo?.userId?.also { userId ->
                    StartCallProxy.builder(this@LiveSpectatorFragment).startCall(
                        mViewModel,
                        UserConst.From.LIVE,
                        UserConst.LastFrom.LIVE_DETAIL,
                        LiveConst.SenderFrom.MANUAL,
                        userId,
                        mLiveInfo?.toUserBasic()
                    )
                }
            }
            //免费礼物点击
            vFooter.setOnFreeGiftListener {
                val userBasic = mLiveInfo?.toUserBasic()
                val objectId = mLiveInfo?.liveId
                if (userBasic != null && objectId != null) {
                    mViewModel.sendFreeGift(userBasic, it, AppConst.BackpackGiftComming.LIVE, objectId)
                }
            }
            //点击隐藏edit
            ViewUtils.registerTouchDown(vShade) {
                vEdit.hideKeyboard()
            }
            //点击屏幕中间关注礼物
            widgetLiveFollower.setOnCallSendGiftList { gift, type ->
                sendGift(gift, type)
            }
            //遮罩消息点击举报
            maskView.setOnMaskReportListener {
                //接收方取message
                val userId = mLiveInfo?.userId
                val nickname = mLiveInfo?.nickname
                if (userId != null && nickname != null) {
                    GlobalPopupManager.showReport(
                        requireContext(), nickname, mViewModel,
                        userId, mLiveInfo?.liveId
                    )
                }
            }
            /**
             * 点击贡献榜
             */
            contributionView.setOnSingleClickListener {
                ContributionListPopup.showPop(requireContext(), this@LiveSpectatorFragment, mViewModel, mAnchorId) {
                }
            }
            vFooter.setOnMoreClickListener {
                mLiveMoreProxy.showVideoMore(
                    objectId = 0,
                    onKeyboardStateListener = {
                        mBinding.vEdit.setKeyboardListerState(it)
                    },
                    mIsOpenGift = mBinding.widgetGift.getIsOpenGift(),
                    mIsOpenSound = mBinding.widgetGift.getIsOpenSound(),
                    onOpenGiftAnimation = {
                        mBinding.widgetGift.setIsOpenGiftAnimation(it)
                    },
                    onOpenGiftSound = {
                        mBinding.widgetGift.setIsOpenSound(it)
                    }, onInvitationFriend = {
                        mLiveInfo?.liveId?.let { liveId ->
                            val fragmentManager = childFragmentManager
                            RoomInvitationFragmentDialog().apply {
                                arguments = bundleOf("liveId" to liveId)
                            }.show(
                                fragmentManager,
                                "RoomInvitationFragmentDialog"
                            )
                        }

                    }
                )
            }
            widgetRoomBanner.setMagicLampListener {
                mLiveInfo?.let { info ->
                    MagicLampPopup.show(this@LiveSpectatorFragment, mViewModel, info.userId, true) {
                        mBinding.vFooter.showGiftDialog(null)
                    }
                }

            }
            barrageView.addReportCallBack {
                GlobalPopupManager.showReport(
                    requireContext(),
                    it.nickname,
                    mViewModel,
                    it.userId,
                    it.userId
                )
            }
        }
    }

    private fun initObserver() {
        //游戏排行榜
        mViewModel.gameRankLiveData.observe(this) { resultState ->
            parseState(resultState, {
                if (!GameUtils.gameRun) {
                    mLiveInfo?.liveId?.let { id ->
                        GameUtils.putShowLiveId(id)
                    }
                    GamePlayWinPopup.show(requireContext(), it) {
                        if (mLiveInfo?.userId != UserManager.getUserId()) { //主播不能点击
                            val roomId = (mLiveInfo?.userId ?: "").toString()
                            GameListPopup.show(
                                requireContext(),
                                GameUtils.getLiveCacheGameList(),
                                roomId
                            )
                        }
                    }
                }
            })
        }
        //直播获取顶部消费列表
        mViewModel.liveConsumeLiveData.observe(this) { (liveId, it) ->
            if (mLiveInfo?.liveId == liveId) {
                mBinding.vHeader.updateConsumeList(it)
                mBinding.widgetRoomBanner.upDataMagicLamp()
            }
        }
        //活动滚动信息刷新
        mViewModel.activitiesScrollLiveData.observe(this) {
            mLiveInfo?.let { info ->
                mBinding.actMarquee.getActivitiesScroll(mViewModel, info.userId)
            }
        }
        //直播间人数定时刷新
        mViewModel.liveUserCountLiveData.observe(this) {
            mLastUserCount = it
            mBinding.vHeader.updateUserCount(if (mAnchorLeave) it else it - 1)
        }
        //获取礼物飘屏用户信息
        mViewModel.giftInfoLiveData.observe(this) { resultState ->
            parseState(resultState, { user ->
                when (user.live?.liveType) {
                    LiveConst.Type.PARTY_LIVE -> {
                        Router.builder(RoutePath.PARTY_SPECTATOR_ACTIVITY)
                            .withInt(LiveConst.Params.LIVETYPE, LiveConst.Type.PARTY_LIVE)
                            .withLong(LiveConst.Params.ANCHORID, user.userId).navigation(requireActivity())
                        mOnCloseListener?.invoke(null)

                    }

                    LiveConst.Type.VIDEO_PARTY -> {
                        Router.builder(RoutePath.PARTY_SPECTATOR_ACTIVITY)
                            .withInt(LiveConst.Params.LIVETYPE, LiveConst.Type.VIDEO_PARTY)
                            .withLong(LiveConst.Params.ANCHORID, user.userId).navigation(requireActivity())
                        mOnCloseListener?.invoke(null)
                    }

                    LiveConst.Type.PARTY_GAME_LIVE -> {
                        Router.instance.setPath(RoutePath.PARTY_GAME_SPECTATOR_ACTIVITY)
                            .withLong(LiveConst.Params.ANCHORID, user.userId).navigation(requireActivity())
                        mOnCloseListener?.invoke(null)

                    }

                    else -> {
                        if (user.live?.living == true) {
                            val coverUrl = user.coverPhoto?.url ?: user.photos.firstOrNull()?.url
                            switchLive(
                                LiveSpectatorBean(
                                    user.userId,
                                    coverUrl,
                                    user.live.liveStreamId,
                                    user.toUserBasicVo(),
                                    false
                                )
                            )
                        }
                    }
                }
            })
        }
        //获取用户信息
        mViewModel.infoLiveData.observe(this) { resultState ->
            parseState(resultState, { user ->
                mBinding.vHeader.setUserFollower(user.relation?.followed)
                mBinding.liveBanner.setCoverBanner(user, viewLifecycleOwner)
                mBinding.vFooter.setUserData(user)
                mGiftProxy = GiftAnimationProxy(this, requireContext(), mBinding.llGift, user.nickname)
                    .apply {
                        //礼物队列点击头像
                        setOnHeadOnClickListener {
                            showUserProfilePopup(it)
                        }
                    }

                if (user.live?.liveType == LiveConst.Type.ONLY_LIVE) {
                    mBinding.vFooter.mBinding.ivCall.visibility = View.GONE
                } else {
                    mBinding.vFooter.mBinding.ivCall.visibility = View.VISIBLE
                }
                if (getLoadCount() <= 1 && isLoading()) {
                    setCurrentCover(user.userId) {
                        val coverUrl = user.coverPhoto?.url ?: user.photos.firstOrNull()?.url
                        if (it == null) {
                            LiveSpectatorBean(
                                user.userId,
                                coverUrl,
                                user.live?.liveStreamId,
                                user.toUserBasicVo()
                            )
                        } else {
                            it.copy(
                                coverUrl = coverUrl
                            )
                        }
                    }
                }
                mAnchorLeave = mLiveInfo?.leave == true

                if (mAnchorLeave) {
                    anchorLeaveLive()
                }
            }, {
                mOnCloseListener?.invoke(null)
            })
        }
        //获取游戏列表
        mViewModel.gameLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.vFooter.updateGameState(it.isNotEmpty())
                GameUtils.setLiveCacheGameList(it)
                mLiveInfo?.liveId?.let { id ->
                    mViewModel.gameRank(id)
                }

            })
        }
        //关注主播
        mViewModel.liveFollowLiveData.observe(this) { resultState ->
            parseState(resultState, {
                ToastGravity.showGravity(R.string.follower_succeed)
                clearFollower()
            }, {
                ToastGravity.showGravity(it.errorMsg)
            })
        }
        mViewModel.liveLoadMoreLiveData.observe(this) { resultState ->
            parseState(resultState, {
                //如果获取是相同的，认为存在问题
                if (it.base.userId == mLiveInfo?.liveId) {
                    reFetchLoadMore()
                } else {
                    embedLiveMoreData(it)
                }
            }, {
                //出错重新获取新的
                reFetchLoadMore()
            })
        }
        //获取主播基础信息并转跳这个主播
        mViewModel.infoUserLiveData.observe(this) { resultState ->
            parseState(resultState, {
                switchLive(it.toDisplayUserBean())
            })
        }
        UserStateManager.observe(this, {
            mLiveMoreData?.bean?.anchorId?.let { listOf(it) } ?: emptyList()
        }, {
            val state = it.firstOrNull()?.state
            val liveMoreUserId = mLiveMoreData?.bean?.anchorId
            if (state != null && liveMoreUserId != null
                && state.living == AppConst.NO && state.userId == liveMoreUserId
            ) {
                refreshLiveMoreData()
            }
        })
        //直播飘屏
        ImLiveManager.observe<SendLiveFloatingMessage>(
            this,
            COMMAND_LIVE_FLOATING,
            { OnLiveObserveListener.ANY_ID }) {
            mBinding.widgetFloat.addFloatView(it)
        }
        //直播关闭消息
        ImLiveManager.observe<SendLiveCloseMessage>(
            this,
            COMMAND_LIVE_CLOSE,
            { mLiveInfo?.liveId }) {
            mOnServerCloseListener?.invoke(it)
        }

        //直播用户加入消息
        ImLiveManager.observeEvent(this) { command, argument ->
            when (command) {
                SFSEvent.USER_ENTER_ROOM -> {
                    val user = argument.getUser()
                    //过滤自己和主播
                    if (user == null
                        || user.name == UserManager.getUserId().toString()
                        || user.name == mLiveInfo?.liveId?.toString()
                    ) {
                        return@observeEvent
                    }
                    argument.getUser()?.parseVariables<LiveEnterBean>()?.let {
                        mEntryScreenAnimationProxy?.addEntryScreenOtherUser(it) {
                            mBinding.vEnter.addEnterBean(it)
                        }
                    }
                }

                SFSEvent.USER_EXIT_ROOM -> {
                    val user = argument.getUser()
                    if (user == null || user.name == UserManager.getUserId().toString()) {
                        return@observeEvent
                    }
                    mEntryScreenAnimationProxy?.removeEntryScreen(user.name.toLong())

                }

                //如果是加入则刷新直播间的信息
                SFSEvent.ROOM_JOIN -> {
                    argument.getRoom()?.also { room ->
                        if (room.getRoomId().toString() == mAnchorId.toString()) {
                            room.variables.forEach {
                                variableUpdate(it)
                            }
                        }
                    }
                    SmartFoxManager.getLiveMyself()?.parseVariables<LiveEnterBean>()?.let {
                        mEntryScreenAnimationProxy?.addEntryScreenMe(it)
                    }
                }
            }
        }
        //直播公屏消息
        ImLiveManager.observePublicMessage(this, { mLiveInfo?.liveId }, { message ->
            if (message.type in ImLiveManager.publicTypes && message.businessId == mLiveInfo?.liveId) {
                mBinding.vMessage.addMessage(message)
                if (message.type == LIVE_PUBLIC_SCREEN) {
                    val ext = message.ext as? MessageUserExtBean?
                    if (ext?.type == 1) { //发送的弹幕消息
                        mBinding.barrageView.addMessage(message)
                    }
                }
            }
            //其他消息处理
            when (message.type) {
                LIVE_SEND_GIFT, LUCKY_BACKPACK_GIFT -> {
                    mGiftProxy?.addAnimation(message)
                    val ext = message.ext as MessageUserExtBean
                    val payload = message.payload as InviteGiftPayloadBean
                    payload.gift.animation?.let { mBinding.widgetGift.setGift(payload) }

                    val isWinning = payload.reward != null && payload.reward.times > 0

                    if (isWinning && UserManager.getUserId() == ext.user.userId) {
                        if (message.type != LUCKY_BACKPACK_GIFT) {
                            GlobalDialogManager.showUserWinning(requireContext(), payload)
                        } else {
                            GlobalDialogManager.showBackPackUserWinning(requireContext(), payload)
                        }
                    }
                }

                //警告消息
                LIVE_WARN_MESSAGE -> {
                    mLivePublicProxy.onPublicMessage(message)
                }
                //礼物列表消息
                LIVE_GIFT_LIST -> {
                    val payload = message.payload as GiftListPayloadBean
                    val orNull = payload.gifts.getOrNull(0)
                    orNull?.let {
                        playAnim(listOf(inAlpha(mBinding.widgetLiveFollower)))
                        mBinding.widgetLiveFollower.setData(
                            payload,
                            mLiveInfo?.avatar,
                            mLiveInfo?.userId
                        )
                        mGiftJob = lifecycleScope.launch(CoroutineScopeManager.ioDispatcher) {
                            delay(payload.duration * 1000)
                            withContext(CoroutineScopeManager.mainDispatcher) {
                                if (mBinding.widgetLiveFollower.isVisible) {
                                    playAnim(listOf(outAlpha(mBinding.widgetLiveFollower)))
                                }
                            }
                        }
                    }
                }
                //遮罩消息
                LIVE_MASKING_MESSAGE -> {
                    mBinding.maskView.maskState(message)
                }

                LIVE_KICK_ROOM -> {
                    ToastGravity.showGravity(message.content)
                    mOnCloseListener?.invoke(null)
                }
                //神灯进度90%
                LIVE_MAGIC_LAMP_90 -> {
                    mBinding.widgetRoomBanner.upDataMagicLamp()
                }
                //神灯开奖
                LIVE_MAGIC_LAMP_OPEN -> {
                    val payload = message.payload as MagicLampCountDownBean
                    mBinding.widgetRoomBanner.upDataMagicLamp()
                    mBinding.widgetMagicLamp.addMagicLampPag(payload)
                }
                //新人免费礼物累计
                NEW_COUPLES_FREE_GIFTS -> {
                    mBinding.vFooter.changeFreeGift()
                }
            }
        })
        //直播变量变化
        ImLiveManager.observeVariableUpdate(this, { mAnchorId }, {
            variableUpdate(it)
        })
        //直播人数变化
        ImLiveManager.observeUserCountChange(this, { mAnchorId }, {
            mLastUserCount = it
            mBinding.vHeader.updateUserCount(if (mAnchorLeave) it else it - 1)
        })
        //发送礼物后如果position不为空那么代表就是送的邀请关注礼物
        mViewModel.sendFollowerLiveData.observe(this) {
            when (it) {
                LiveConst.SendGift.giftPopup -> if (mBinding.vFooter.isShowComboView()) {
                    mBinding.icRun.showView()
                }

                LiveConst.SendGift.followerGift -> clearFollower()
            }
        }
        //发送礼物后得到返回的数量数据
        mViewModel.sendGiftLiveData.observe(this) {
            mBinding.vFooter.upBackpackIdAllCount(it.backpackId, it.ext)
        }
        mViewModel.recoverJoinLiveData.observe(this) {
            if (it == null) {
                //房间都加入成功了，没道理网络和im没连上
                mBinding.vNetwork.setNetworkState(isNetwork = true, isConnected = true)
            } else {
                //直播im是连接的，但是重新加入直播间失败，延迟1秒重试
                if (SmartFoxManager.isLiveConnected()) {
                    mViewModel.recoverJoinLive(mAnchorId, 1000)
                }
                LogExt.logE("--live", "recoverJoin", it)
            }
        }
        //路由监听
        RouterControlManager.observeListener(this) { key, ext ->
            withLoaded {
                when (key) {
                    RouterControlManager.ROUTER_ROOMGAME -> { //打开幸运游戏列表
                        val gameId = ext["gameId"]?.toLongOrNull()
                        if (gameId == null) {
                            showGameList()
                        } else {
                            val gameVo = GameUtils.getLiveCacheGameList()
                                ?.asSequence()
                                ?.flatMap { it.list.asSequence() }
                                ?.find { it.gameID == gameId }
                            if (gameVo != null) {
                                val roomId = mLiveInfo?.userId.toString()
                                GameUtils.showGameFragment(requireContext(), gameVo, roomId = roomId)
                            } else {
                                showGameList()
                            }
                        }
                    }

                    RouterControlManager.ROUTER_GIFT -> { //礼物盘拉起
                        val giftType = ext["giftType"]?.toIntOrNull()
                        mBinding.vFooter.showGiftDialog(null, giftType = giftType ?: -1)
                    }
                }
            }
        }

        mViewModel.mBackGiftRedData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.vFooter.setBackPackRed(if (it) View.VISIBLE else View.GONE)
            })
        }
        TaskRedProxy.observe(this, object : TaskRedListener {
            override fun updateRed(isRed: Boolean) {
                mBinding.vFooter.setMoreRed(if (isRed) View.VISIBLE else View.GONE)
            }
        })
        mViewModel.mLampLotteryLiveData.observe(this) { resultState ->
            parseState(resultState, {
                MagicLampWinRewardPopup.show(requireContext(), it)
            }) {
                ToastGravity.showGravity(it.errorMsg)
            }
        }
        mBinding.widgetMagicLamp.openMagicLampCallBack {
            mLiveInfo?.userId?.let { userId ->
                mViewModel.lampLottery(userId, it.index.toLong())
            }
        }
        //更新弹幕信息
        mViewModel.barrageNumberLiveData.observe(this) { resultState ->
            parseState(resultState, {
                mBinding.vEdit.upBarrage(it)
            })
        }
    }

    private fun showGameList() {
        val roomId = (mLiveInfo?.userId ?: "").toString()
        GameListPopup.show(requireContext(), GameUtils.getLiveCacheGameList(), roomId)
    }

    private fun variableUpdate(variable: RoomVariable) {
        val liveInfo = mLiveInfo ?: return

        LiveUtils.fillLiveInfo(liveInfo, variable)

        when (variable.name) {
            "showGainCoins" -> {
                mBinding.contributionView.showGainCoins(liveInfo.showGainCoins?.formatNumberWithK() ?: "0")
            }

            "leave" -> {
                mAnchorLeave = liveInfo.leave
                mBinding.vHeader.updateUserCount(if (mAnchorLeave) mLastUserCount else mLastUserCount - 1)

                if (liveInfo.leave) {
                    anchorLeaveLive()
                } else {
                    anchorEnterLive()
                }
            }
            "roomTheme" -> {
                setSkinUi()
            }
        }
    }

    //赠送礼物
    private fun sendGift(gift: GiftBean, type: Int) {
        val userId = mLiveInfo?.userId
        val liveId = mLiveInfo?.liveId
        if (userId != null && liveId != null) {
            val sendGiftBean = SendGiftBean(
                recipient = userId,
                giftId = gift.id,
                count = 1,
                sourceType = gift.sourceType,
                objectId = liveId,
                payload = gift.payload
            )
            mViewModel.sendGift(requireContext(), sendGiftBean, type, gift.pic)

            if (type == LiveConst.SendGift.followerGift) {
                mBinding.vHeader.updateFollowStatus(true)
            }
            if (mBinding.widgetLiveFollower.isVisible) {
                mGiftJob?.cancel()
                playAnim(listOf(outAlpha(mBinding.widgetLiveFollower)))
            }
        }
    }

    private fun embedLiveMoreData(liveData: DisplayUserBean) {
        mLiveMoreAttempt = 0
        mLiveMoreData = LiveDisplayUserVo(liveData, liveData.toLiveSpectatorBean()).apply {
            addSwitchData(bean)
        }
    }

    private fun refreshLiveMoreData() {
        mLiveMoreData?.bean?.also { current ->
            removeFooterData {
                //只删除内存相同的
                it === current
            }
        }
        mLiveMoreData = null
        mViewModel.getLoadMore(mAnchorId)
    }

    private fun reFetchLoadMore() {
        mViewModel.getLoadMore(mAnchorId, LazyUtils.exponentialBackoff(mLiveMoreAttempt++))
    }

    override fun initData() {
        fetchAnchorData()
    }

    private fun fetchAnchorData() {
        mLiveMoreData = null
        mViewModel.getInfoUser(
            mAnchorId,
            UserManager.RELATIONSHIP_INFORMATION,
            UserManager.ALBUM_INFORMATION,
            UserManager.LIVE_INFORMATION,
            UserManager.COVER_INFORMATION,
            UserManager.ALBUM_INFORMATION,
            UserManager.BASIC_INFORMATION,
            UserManager.DECORATIVE_DISPLAY
        )
        mViewModel.getLoadMore(mAnchorId)
    }

    private fun showLayout(allLayout: Boolean = true) {
        handleLayoutView(View.VISIBLE)

        if (!allLayout) {
            hideLiveLayout()
        }
    }

    private fun hideLayout() {
        handleLayoutView(View.GONE)

        mBinding.vHeader.visibility = View.INVISIBLE
    }

    private fun hideInfoLayout() {
        mBinding.apply {
            vHeader.visibility = View.INVISIBLE
            llTop.visibility = View.GONE
        }
    }

    private fun hideLiveLayout() {
        mBinding.llTop.visibility = View.GONE
    }

    private fun handleLayoutView(visibility: Int) {
        mBinding.apply {
            val views =
                listOf(vHeader, llTop, llGift, vMessage, vFooter, widgetRoomBanner)

            views.forEach {
                it.visibility = ViewUtils.getViewVisible(it) ?: visibility
            }
        }
    }

    /**
     * 不显示轮播图
     */
    fun anchorEnterLive() {
        withLoaded {
            if (!mAnchorLeave) {
                mBinding.liveBanner.setShowView(false)
                mBinding.llWillBack.visibility = View.GONE
            }
        }
    }

    /**
     * 显示轮播图
     */
    fun anchorLeaveLive(forceLeave: Boolean = false) {
        withLoaded {
            if (mAnchorLeave || forceLeave) {
                mBinding.liveBanner.setShowView(true)
                if (mLiveInfo?.type != LiveConst.Type.ONLY_LIVE) { //仅直播不显示
                    mBinding.llWillBack.visibility = View.VISIBLE
                }
            }
        }
    }

    fun startLoading(needLoading: Boolean, bean: LiveSpectatorBean) {
        withLoaded {
            //不管如何先把当前的加入进去，这里的0代表初始化
            addSwitchData(bean, 0)

            if (needLoading) {
                hideLayout()
                super.startLoading()
            } else {
                hideInfoLayout()
            }
        }
    }

    fun switchLoading(needLoading: Boolean, bean: LiveSpectatorBean) {
        withLoaded {
            if (!needLoading) {
                showLayout(false)
            }
        }
    }

    fun preUserInfo(userBasic: UserBasicVo) {
        //这里预先加载部分用户信息
        withLoaded {
            showLayout(false)

            mBinding.vHeader.initData(pageType, userBasic)
        }
    }

    fun initLiveInfo(data: LiveInitInfo) {
        withLoaded {
            val variable = data.info

            mLiveInfo = variable

            mViewModel.getGameList(variable.liveId)

            mAnchorLeave = mLiveInfo?.leave == true
            mLastUserCount = data.userCount

            mBinding.apply {
                vHeader.initData(pageType, variable, data.userCount)
                vMessage.initData(pageType, variable)
                vFooter.initData(variable)
                vEdit.initData(variable)
                contributionView.showGainCoins(mLiveInfo?.showGainCoins?.formatNumberWithK() ?: "0")
                liveBanner.setShowView(variable.leave)
                widgetRoomBanner.initBannerData(lifecycle, mViewModel, variable.liveId, variable.userId)
                CommonCache.getMagicLampList().forEach { widgetMagicLamp.addMagicLampPag(it) }
            }

            loadSuccess(false)
            val route = mH5ChildRouter
            if (route != null) {
                RouterUtils.routerGoto(route)
                mH5ChildRouter = null
            }
        }
        setSkinUi()
    }

    private fun clearFollower() {
        mBinding.vMessage.getMessageView().clearFollower()
        mBinding.vHeader.updateFollowStatus(true)
    }

    override fun loadSuccess(playSuccessful: Boolean) {
        withLoaded {
            super.loadSuccess(playSuccessful)

            showLayout()

            //加载成功开始获取消费列表
            mLiveInfo?.liveId?.also {
                mViewModel.launchConsumeUser(it)
            }
        }
    }

    override fun playSuccessful() {
        withLoaded {
            super.playSuccessful()
        }
    }

    override fun loadFailure(message: String, isScroll: Boolean) {
        withLoaded {
            startLoading()
            hideLayout()
            super.loadFailure(message, isScroll)
        }
    }

    override fun onScrollView(offset: Int) {
        mOnScrollViewListener?.onScroll(offset)
    }

    private fun isSameLive(newBean: LiveSpectatorBean): Boolean {
        val currentStreamId = mLiveInfo?.streamId
        return newBean.anchorId == mAnchorId
                && newBean.streamId != null && currentStreamId != null
                && newBean.streamId == currentStreamId
    }

    private fun switchLive(bean: DisplayUserBean) {
        switchLive(
            LiveSpectatorBean(
                bean.base.userId,
                bean.cover,
                bean.playStreamId,
                bean.base
            )
        )
    }

    private fun switchLive(bean: LiveSpectatorBean) {
        //如果主播的id，并且流id都相同则不需要切换
        if (isSameLive(bean)) {
            return
        }

        //这里切换设置当前的索引的数据
        setCurrentPageItem(bean)

        onSwitchView(bean)
    }

    override fun onSwitchView(bean: LiveSpectatorBean) {
        mBinding.icRun.viewGone()
        resetLive(bean.anchorId)
        mOnSwitchLiveListener?.onSwitchLive(bean)
        //这里同步请求主播的数据
        fetchAnchorData()
    }

    override fun onNetwork(isNetwork: Boolean, isConnected: Boolean) {
        withLoaded {
            val lastRoom = SmartFoxManager.getLiveRoom()

            //如果上次是断开连接，这次连接上了，需要重连
            if (lastRoom == null && isConnected) {
                mViewModel.recoverJoinLive(mAnchorId)
            }

            val finalIsConnected = if (lastRoom != null && !isConnected) {
                true
            } else {
                isConnected
            }

            mBinding.vNetwork.setNetworkState(isNetwork, finalIsConnected)
        }
    }

    //重置直播间UI
    private fun resetLive(anchorId: Long) {
        mBinding.apply {
            vHeader.reset()
            vMessage.reset()
            vFooter.reset()
            vEdit.reset()
            mGiftProxy?.reset()
            actMarquee.reset()
            mEntryScreenAnimationProxy?.reset()
            mBinding.widgetGift.clearAllPag()
            GlobalDialogManager.dismissWinningDialog()
        }

        mViewModel.resetLiveJob()

        mAnchorId = anchorId
        mLiveInfo = null
    }

    override fun isScroll(): Boolean {
        return (mLiveInfo != null || isLoadError()) && super.isScroll()
    }

    override fun isGesture(): Boolean {
        return mLiveInfo != null && !mIsShowDrawer && super.isGesture()
    }

    override fun onShowView() {
        val width = ScreenUtils.getScreenWidth()

        playAnim(
            listOf(
                inLeft(mBinding.vMessage, width),
                inLeft(mBinding.vFooter.mBinding.ivSend, width),
                inLeft(mBinding.vHeader.mBinding.rvRecycler, width),
                inLeft(mBinding.widgetRoomBanner, width),
            )
        )
    }

    override fun onHideView() {
        val width = ScreenUtils.getScreenWidth()

        playAnim(
            listOf(
                outRight(mBinding.vMessage, width),
                outRight(mBinding.vFooter.mBinding.ivSend, width),
                outRight(mBinding.vHeader.mBinding.rvRecycler, width),
                outRight(mBinding.widgetRoomBanner, width),
            )
        )
    }

    override fun onShowRightView() {
        mIsShowDrawer = true

        XPopup.Builder(requireContext())
            .isViewMode(true)
            .hasShadowBg(false)
            .popupPosition(PopupPosition.Right)
            .setPopupCallback(object : XpopupCallBackImpl {
                override fun onDismiss(popupView: BasePopupView) {
                    mIsShowDrawer = false
                }
            })
            .asCustom(mLiveDrawerPopup)
            .show()
    }

    override fun onPlayerState(quality: ZegoPlayStreamQuality) {
    }

    private fun showUserProfilePopup(userId: Long) {
        GlobalPopupManager.showUserProfilePopup(
            requireContext(), this, mViewModel,
            userId, UserConst.From.LIVE, mLiveInfo?.liveId,
            goneBottom = false,
            onMessageClickListener = {
                showChatMessage(it.toUserBasicVo())
            }, onSelectMoreCardListener = {
                showSelectCard(it)
            },
            onGiftClickListener = {
                mBinding.vFooter.showGiftDialog(it)
            })
    }

    /**
     * 更新皮肤
     */
    private fun setSkinUi() {
        val themeData = AppConfigManager.getUserTheme(mLiveInfo?.roomTheme)
        mBinding.vFooter.setTheme(themeData)
    }

    private fun showSelectCard(infoOtherResp: InfoOtherResp) {
        GlobalPopupManager.showLiveSelectMoreCard(
            requireContext(), this, mViewModel,
            infoOtherResp, mLiveInfo?.liveId, mLiveInfo?.userId,
            isCall = false,
            onAtClickListener = {
                mBinding.vEdit.atUser(infoOtherResp.userId, infoOtherResp.nickname)
            }
        )
    }

    /**
     * 展示消息列表
     */
    private fun showChatMessage(userBase: UserBasicVo) {
        childFragmentManager.showNewDialogFragment(
            MessageSingleDialogFragment(
                userBase.userId,
                userBase.avatar,
                userBase.avatarFrame,
                userBase.chatBubble,
                nestedPage = false,
                singlePage = true
            ),
            MessageSessionFragment.FRAGMENT_TAG
        )
    }

    fun setOnScrollViewListener(l: OnScrollViewListener) {
        mOnScrollViewListener = l
    }

    fun setOnSwitchLiveListener(l: OnSwitchLiveListener) {
        mOnSwitchLiveListener = l
    }

    fun setOnCloseListener(l: (SendLiveCloseMessage?) -> Unit) {
        mOnCloseListener = l
    }

    fun setOnServerCloseListener(l: (SendLiveCloseMessage?) -> Unit) {
        mOnServerCloseListener = l
    }

    companion object {

        private const val pageType = LiveConst.Page.LIVE_SPECTATOR
    }

    override fun setOnSwitchRoomListener(anchorId: Long?, childRouter: String?) {
        withLoaded {
            if (anchorId != null && anchorId != mLiveInfo?.userId) {
                mViewModel.getInfoUserData(anchorId)
                mH5ChildRouter = childRouter
            } else {
                childRouter?.let { RouterUtils.routerGoto(it) }
            }
        }
    }

}

fun interface OnScrollViewListener {

    fun onScroll(offset: Int)

}

fun interface OnSwitchLiveListener {

    fun onSwitchLive(bean: LiveSpectatorBean)

}